package network;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

public class Message implements Serializable {
    private static final List<String> validKeys = Arrays.asList("/snd", "/chid", "/hist", "/chroom");
    private String sender = "Anonymous";
    private String room = "default";
    private String recipient = "Admin";
    private String key = "/snd";
    private String message = "";
    private Date date;
    public static final int maxMessageLength = 150;

    public Message() {
    }

    public Message(String sender, String recipient, String key, String message, Date date) {
        this.sender = sender;
        this.recipient = recipient;
        this.key = key;
        this.message = message;
        this.date = date;
    }

    public String getRoom() {
        return room;
    }

    public void setRoom(String room) {
        this.room = room;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public String getSender() {
        return sender;
    }

    public String getKey() {
        return key;
    }

    public String getMessage() {
        return message;
    }

    public void setSender(String sender) {
        this.sender = sender;
    }

    public boolean parseRequest(String request) {
        if (!setKey(request.split(" ")[0])) {
            return false;
        }
        return setMessage(request.replaceFirst(key, "").trim());
    }

    public boolean isValid() {
        return isValidKey(key) && isValidMessage(message) && (isValidCHID() || isValidSND() || isValidHIST() || isValidCHROOM());
    }

    private boolean isValidHIST() {
        return !"Anonymous".equals(sender) && "/hist".equals(key) && "".equals(message.trim());
    }

    private boolean isValidSND() {
        return !"Anonymous".equals(sender) && "/snd".equals(key) && !"".equals(message.trim());
    }

    public boolean isValidCHROOM() {
        return !"Anonymous".equals(sender) && "/chroom".equals(key) && message.trim().matches("\\w{0,150}");
    }

    public boolean isValidCHID() {
        return "/chid".equals(key) && message.trim().matches("\\w{0,150}");
    }

    private boolean setKey(String newKey) {
        if (!isValidKey(newKey)) {
            return false;
        }
        key = newKey;
        return true;
    }

    public boolean setMessage(String newMessage) {
        if (!isValidMessage(newMessage)) {
            return false;
        }
        this.message = newMessage;
        return true;
    }

    private boolean isValidKey(String line) {
        return validKeys.contains(line);
    }

    private boolean isValidMessage(String line) {
        if (line == null || line.length() > maxMessageLength) {
            return false;
        }
        return true;
    }

    public boolean isSenderAdmin() {
        return "Admin".equals(getSender());
    }

    public boolean isSuccess() {
        return "success".equals(getMessage());
    }

    public String getRecipient() {
        return recipient;
    }

    public void setRecipient(String recipient) {
        this.recipient = recipient;
    }

    public static Message fromString (String line) {
        Message parsed = new Message();
        parsed.setKey("/snd");
        parsed.setDate(new Date());
        parsed.setSender(line.split("> ")[1]);
        parsed.setMessage(line.substring(parsed.getDate().toString().length() + parsed.getSender().length(), line.length()));
        return parsed;
    }

    @Override
    public String toString() {
        return getDate() + "> " + getSender() + "> " + getMessage();
    }
}
